"Interpolation Tweens" discusses tween operations that modify other tween operations by feeding them artificial time values in place of real time. Listing 20 shows how to create an interpolation tween.
Listing 20 Creating an interpolation tween container
OSErr CreateSampleInterpolatedTweenContainer( QTAtomContainer container,
TimeValue duration, QTAtom *newTweenAtom )
{
OSErr err = noErr;
Handle pathData = nil;
err = QTRemoveChildren( container, kParentAtomIsContainer );
if ( err )goto bail;
err = CreateSampleLongTweenContainer( container, 0, duration,
duration, newTweenAtom );
if ( err ) goto bail;
pathData = CreateSampleVectorData( 3 );
if ( ! pathData ) { err = memFullErr; goto bail; }
err = AddXtoYInterpolatorTweenerForDataSet( container, *newTweenAtom,
*newTweenAtom, 1, pathData );
if ( err ) goto bail;
bail:
if ( pathData )DisposeHandle( pathData );
return err;
}
OSErr AddXtoYInterpolatorTweenerForDataSet( QTAtomContainer container,
QTAtom sequenceTweenAtom, QTAtom tweenAtom, QTAtomID dataSetID,
Handle vectorCodecData )
{
OSErr err = noErr;
QTAtomID interpolationTweenID;
QTAtom dataSetAtom, interpolatorTweenAtom, durationAtom,
interpolatorIDAtom;
TimeValue duration;
ComponentInstance ci = nil;
UInt8 saveState;
gxPaths *thePathData;
long dataSize, numPoints;
gxPoint firstPoint, lastPoint;
Boolean ptIsOnPath;
Fixed minOutput, maxOutput;
if ( (! container) || (! dataSetID) || (! vectorCodecData) )
{ err = paramErr; goto bail; }
saveState = HGetState( vectorCodecData );
dataSetAtom = QTFindChildByID( container, tweenAtom, kTweenData,
dataSetID, nil );
if ( ! dataSetAtom ) { err = cannotFindAtomErr; goto bail; }
// determine duration of tweenEntry so we can use the same duration
// for the interpolator tween
durationAtom = QTFindChildByIndex( container, tweenAtom,
kTweenDuration, 1, nil );
if ( ! durationAtom ) { err = cannotFindAtomErr; goto bail; }
err = QTCopyAtomDataToPtr( container, durationAtom, false,
sizeof(duration), &duration, nil );
if ( err ) goto bail;
// determine the minOutput and maxOutput values based for the given
// vector codec data
err = OpenADefaultComponent( decompressorComponentType,
kVectorCodecType, &ci );
if ( err ) goto bail;
HLock( vectorCodecData );
err = CurveGetAtomDataFromVectorStream ( ci, vectorCodecData,
kCurvePathAtom, &dataSize, (Ptr *)&thePathData );
if ( err ) goto bail;
err = CurveCountPointsInPath( ci, thePathData, 0,
(unsigned long *)&numPoints );
if ( err ) goto bail;
err = CurveGetPathPoint( ci, thePathData, 0, 0, &firstPoint,
&ptIsOnPath );
if ( err ) goto bail;
err = CurveGetPathPoint( ci, thePathData, 0, numPoints - 1,
&lastPoint, &ptIsOnPath );
if ( err ) goto bail;
minOutput = firstPoint.x;
maxOutput = lastPoint.x;
// add interolator tween atom with any unique id
err = AddTweenAtom( container, sequenceTweenAtom, 0,
kTweenTypePathXtoY, 0, duration, minOutput,
maxOutput, nil, &interpolatorTweenAtom );
if ( err ) goto bail;
// so what was that unique id?
err = QTGetAtomTypeAndID( container, interpolatorTweenAtom, nil,
&interpolationTweenID );
if ( err ) goto bail;
err = AddDataAtom( container, interpolatorTweenAtom, 1,
GetHandleSize( vectorCodecData ),
*vectorCodecData, nil, 0, nil );
if ( err ) goto bail;
// finally, we need to reference this new interpolator tween
interpolatorIDAtom = QTFindChildByID( container, tweenAtom,
kTweenInterpolationID, dataSetID, nil );
if ( ! interpolatorIDAtom ) {
err = QTInsertChild( container, tweenAtom, kTweenInterpolationID,
dataSetID, 0, 0, nil, &interpolatorIDAtom );
if ( err ) goto bail;
}
err = QTSetAtomData( container, interpolatorIDAtom,
sizeof(interpolationTweenID), &interpolationTweenID );
if ( err ) goto bail;
bail:
if ( vectorCodecData )
HSetState( vectorCodecData, saveState );
return err;
}
To scale the output of an interpolation tween, you add the optional kTweenOutputMaxValue atom and kTweenOutputMinValue atom.
| Previous | Chapter Contents | Chapter Top | Next |